package com.trantronghien85.websocketdemo;
import android.content.Intent;

import android.app.Activity;
import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;
import androidx.appcompat.widget.Toolbar;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.WebSocket;
import okio.ByteString;
import android.widget.ListView;
import java.util.Random;
import android.view.Menu;

import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity implements WebsSocketClientListener {
	final private  static String LOG_TAG="wschat";
	private final int IPC_ID = 1122;	
    private Button btnSend;
    private Button btnReconnect;
    private Button btnClearMessage;
    private Button btnDisconnect;
    private EditText edtMessage;
    private TextView txtStatus;
    private TextView txtContent;
    private OkHttpClient client;

    private   String URL;

    private MessageAdapter messageAdapter;
    private ListView messagesView;

    private WebSocket ws;
    private final String TAG = "ws-test";
    private StringBuilder  message;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
		
        // Find the toolbar view inside the activity layout
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        // Sets the Toolbar to act as the ActionBar for this Activity window.
        // Make sure the toolbar exists in the activity and is not null
        setSupportActionBar(toolbar);
		
        message = new StringBuilder();
        btnSend = findViewById(R.id.btnSend);
        btnReconnect = findViewById(R.id.btnReconnect);
        btnClearMessage = findViewById(R.id.btnClearMessage);
        btnDisconnect = findViewById(R.id.btnDisconnect);
        edtMessage = findViewById(R.id.txtMessage);
        txtContent = findViewById(R.id.txtContent);
        txtStatus = findViewById(R.id.txtStatus);
        client = new OkHttpClient.Builder().build();
        messageAdapter = new MessageAdapter(this);
        messagesView = (ListView) findViewById(R.id.messages_view);
        messagesView.setAdapter(messageAdapter);		
        btnReconnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
				if(URL!=null){
                  connectClient();
				}

            }
        });

        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sendMessage();
            }
        });

        btnClearMessage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                message.setLength(0);
                txtContent.setText(message.toString());
            }
        });

        btnDisconnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                shutdown();
                changeStatus(false);
            }
        });

        loadUrl();
        connectClient();
    }
    // Menu icons are inflated just as they were with actionbar
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    private void connectClient() {
        if(URL!=null) {
            Request request = new Request.Builder()
                    .url(URL)
                    .build();
            EchoWebSocketListener listener = new EchoWebSocketListener(this);
            ws = client.newWebSocket(request, listener);
        }
    }

    private void sendMessage() {
        String textClientSend = edtMessage.getText().toString();
        message.append(textClientSend);
        message.append("->\n\n");
        ws.send(textClientSend);
        setTextMessage();
        edtMessage.setText("");
		MemberData data = new MemberData(getRandomName(), getRandomColor());
        messageAdapter.add(new Message(textClientSend,data,true));

    }

    private void shutdown() {
        //client.dispatcher().executorService().shutdown();
        ws.close(1000 , "close android client");
    }

    @Override
    public void onOpenConnect(WebSocket client) {
        ws = client;
        changeStatus(true);
        Log.d(TAG, "onOpenConnect: ");

    }

    @Override
    public void onReceived(String text) {
        message.append(text);
        message.append("<-\n\n");
        setTextMessage();
        MemberData data = new MemberData(getRandomName(), getRandomColor());
        Message msg=new Message(text,data,false);
        messageAdapter.add(msg);
    }

    private void setTextMessage() {
        this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                //txtContent.setText(message.toString());
           }
        });
    }

    @Override
    public void onReceivedByte(ByteString bytes) {
        Log.d(TAG, "onReceivedByte: " + bytes.utf8());
    }

    @Override
    public void onClosing(int code) {
        Log.d(TAG, "onClosing: " + code);
        changeStatus(false);
        showErrorMessage("Close connect");
    }

    @Override
    public void onFailure(String message) {
        Log.d(TAG, "onFailure: " + message);
        showErrorMessage(message);
        changeStatus(false);
    }

    private void showErrorMessage(final String message) {
        this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void changeStatus(final boolean connenct) {
        handler.sendEmptyMessage(connenct?1:0);
    }

    @Override
    protected void onDestroy() {
        client.dispatcher().executorService().shutdown();
        super.onDestroy();
    }

    private String getRandomName() {
        String[] adjs = {"autumn", "hidden", "bitter", "misty", "silent", "empty", "dry", "dark", "summer", "icy", "delicate", "quiet", "white", "cool", "spring", "winter", "patient", "twilight", "dawn", "crimson", "wispy", "weathered", "blue", "billowing", "broken", "cold", "damp", "falling", "frosty", "green", "long", "late", "lingering", "bold", "little", "morning", "muddy", "old", "red", "rough", "still", "small", "sparkling", "throbbing", "shy", "wandering", "withered", "wild", "black", "young", "holy", "solitary", "fragrant", "aged", "snowy", "proud", "floral", "restless", "divine", "polished", "ancient", "purple", "lively", "nameless"};
        String[] nouns = {"waterfall", "river", "breeze", "moon", "rain", "wind", "sea", "morning", "snow", "lake", "sunset", "pine", "shadow", "leaf", "dawn", "glitter", "forest", "hill", "cloud", "meadow", "sun", "glade", "bird", "brook", "butterfly", "bush", "dew", "dust", "field", "fire", "flower", "firefly", "feather", "grass", "haze", "mountain", "night", "pond", "darkness", "snowflake", "silence", "sound", "sky", "shape", "surf", "thunder", "violet", "water", "wildflower", "wave", "water", "resonance", "sun", "wood", "dream", "cherry", "tree", "fog", "frost", "voice", "paper", "frog", "smoke", "star"};
        return (
            adjs[(int) Math.floor(Math.random() * adjs.length)] +
            "_" +
            nouns[(int) Math.floor(Math.random() * nouns.length)]
        );
    }

    private String getRandomColor() {
        Random r = new Random();
        StringBuffer sb = new StringBuffer("#");
        while(sb.length() < 7){
            sb.append(Integer.toHexString(r.nextInt()));
        }
        return sb.toString().substring(0, 7);
    }	
    // methods to control the operations that will
    // happen when user clicks on the action buttons
    @Override
    public boolean onOptionsItemSelected( @NonNull MenuItem item ) {
  
        switch (item.getItemId()){
            case R.id.miCompose:
                Toast.makeText(this, "compose Clicked", Toast.LENGTH_SHORT).show();
                break;

            case R.id.miSetting:
			    setting();
                Toast.makeText(this, "settings Clicked", Toast.LENGTH_SHORT).show();
                break;
        }
        return super.onOptionsItemSelected(item);
    }	
   private void loadUrl(){
        Config cfg=Config.get();
        cfg.load(this);
        URL=cfg.getUrl();
   }
   
	private void setting() {
		
			try {
				Intent myIntentA1A2 = new Intent(MainActivity.this,
						SettingActivity.class);
/*
				Bundle myData = new Bundle();
				myData.putString("myString1", "Hello Android");
				myData.putDouble("myDouble1", 3.141592);
				int[] myLittleArray = { 1, 2, 3 };
				myData.putIntArray("myIntArray1", myLittleArray);

				myIntentA1A2.putExtras(myData);
*/
				startActivityForResult(myIntentA1A2,IPC_ID);
			} catch (Exception e) {
				Toast.makeText(getBaseContext(), e.getMessage(),
						Toast.LENGTH_LONG).show();
			}	
		
    }
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		try {
			switch (requestCode) {
			case IPC_ID: {
				if (resultCode == Activity.RESULT_OK) {

					//Bundle myReturnedData = data.getExtras();
					//String myReturnedIP = myReturnedData.getString("ip");
					//String myReturnedPort = myReturnedData.getString("port");

					loadUrl();
					//Log.d(log_TAG.myReturnedIP + "\n" + myReturnedPort + "\n");
				} else {

					//label1.setText("Selection CANCELLED!");
				}
				break;
			}
			}
		} catch (Exception e) {
			Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_LONG)
					.show();
		}
	}

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(android.os.Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                        txtStatus.setText("Closed");
                        txtStatus.setTextColor(Color.RED);
                        btnSend.setEnabled(false);
                        break;
                case 1:
                        txtStatus.setText("connected");
                        txtStatus.setTextColor(Color.BLUE);
                        btnSend.setEnabled(true);
                        break;
            }
        }
    };

}

